from py2neo import Graph, Node, Relationship
import configparser

#print(neo4j_url,neo4j_username,neo4j_password)
class Neo4jToJson:

    def __init__(self):
        cf = configparser.ConfigParser()
        cf.read("./kg.conf")  # 读取配置文件，如果写文件的绝对路径，就可以不用os模块
        neo4j_url = cf.get("neo4j", "url")  
        neo4j_username = cf.get("neo4j", "username")  
        neo4j_password = cf.get("neo4j", "password")  
        self.graph = Graph(neo4j_url,username=neo4j_username,password=neo4j_password)

    def start(self):
        return self.query("企业", "上海汇严信息科技有限公司")

    def expand(self, node):
        return self.query(node["label"], node["name"])

    def query(self, label, name):
        s_rels = self.graph.run("MATCH r=(n:`{0}`)-[]->() WHERE n.name = '{1}' RETURN r" \
                    .format(label, name)).data()
        t_rels = self.graph.run("MATCH r=(n:`{0}`)<-[]-() WHERE n.name = '{1}' RETURN r" \
                    .format(label, name)).data()
        nodes = list()
        rels = list()
        for rel in s_rels:
            s_node = self.create_node(rel["r"].start_node)
            t_node = self.create_node(rel["r"].end_node)
            rel_label = list(rel["r"].relationships[0].types())[0]
            cur_rel = {"source": s_node["id"], "target": t_node["id"], "label": rel_label}
            if cur_rel not in rels:
                rels.append(cur_rel)
            if s_node not in nodes:
                nodes.append(s_node)
            if t_node not in nodes:
                nodes.append(t_node)
        for rel in t_rels:
            s_node = self.create_node(rel["r"].end_node)
            t_node = self.create_node(rel["r"].start_node)
            rel_label = list(rel["r"].relationships[0].types())[0]
            cur_rel = {"source": s_node["id"], "target": t_node["id"], "label": rel_label};
            if cur_rel not in rels:
                rels.append(cur_rel)
            if s_node not in nodes:
                nodes.append(s_node)
            if t_node not in nodes:
                nodes.append(t_node)
        return {"nodes": nodes, "links": rels}

    def query_by_lable(self, label,gettype=0):
        s_rels=[]
        t_rels=[]
        if gettype==0:
            s_rels = self.graph.run("MATCH r=(n:`{0}`)-[]->()  RETURN r limit 20" \
                    .format(label)).data()
            t_rels = self.graph.run("MATCH r=(n:`{0}`)<-[]-()  RETURN r  limit 20" \
                    .format(label)).data()
        else:
            s_rels = self.graph.run("MATCH r=(n)-[l:{0}]->()  RETURN r limit 20" \
                    .format(label)).data()
            t_rels = self.graph.run("MATCH r=(n)<-[l:{0}]-()  RETURN r  limit 20" \
                    .format(label)).data()
        nodes = list()
        rels = list()
        for rel in s_rels:
            s_node = self.create_node(rel["r"].start_node)
            t_node = self.create_node(rel["r"].end_node)
            rel_label = list(rel["r"].relationships[0].types())[0]
            cur_rel = {"source": s_node["id"], "target": t_node["id"], "label": rel_label};
            if cur_rel not in rels:
                rels.append(cur_rel)
            if s_node not in nodes:
                nodes.append(s_node)
            if t_node not in nodes:
                nodes.append(t_node)
        for rel in t_rels:
            s_node = self.create_node(rel["r"].end_node)
            t_node = self.create_node(rel["r"].start_node)
            rel_label = list(rel["r"].relationships[0].types())[0]
            cur_rel = {"source": s_node["id"], "target": t_node["id"], "label": rel_label}
            if cur_rel not in rels:
                rels.append(cur_rel)
            if s_node not in nodes:
                nodes.append(s_node)
            if t_node not in nodes:
                nodes.append(t_node)
        return {"nodes": nodes, "links": rels}

    def create_node(self, neo4j_node):
        node = {"id": neo4j_node["id"], "label": neo4j_node["label"], "name": neo4j_node["name"]}
        if "image" in neo4j_node:
            node["image"] = neo4j_node["image"]
        return node


    def com_query(self, neosql):
        s_rels=[]
        s_rels = self.graph.run(neosql).data()
        nodes = list()
        rels = list()
        for rel in s_rels:
            s_node = self.create_node(rel["r"].start_node)
            t_node = self.create_node(rel["r"].end_node)
            if len(rel["r"].relationships)==0:
                rel_label = ''
            else:
                rel_label = list(rel["r"].relationships[0].types())[0]
                cur_rel = {"source": s_node["id"], "target": t_node["id"], "label": rel_label};
                if cur_rel not in rels:
                    rels.append(cur_rel)
            if s_node not in nodes:
                nodes.append(s_node)
            if t_node not in nodes:
                nodes.append(t_node)
        return {"nodes": nodes, "links": rels}

if __name__ == '__main__':
    neo4j = Neo4jToJson()
    neo4j.start()
